package com.frank.oj.manager;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.frank.model.entity.contest.Contest;
import com.frank.model.entity.contest.ContestPrint;
import com.frank.model.entity.contest.ContestRecord;
import com.frank.oj.common.exception.StatusFailException;
import com.frank.oj.common.exception.StatusForbiddenException;
import com.frank.oj.constant.Constants;
import com.frank.oj.model.dto.CheckACDTO;
import com.frank.oj.service.entity.contest.ContestEntityService;
import com.frank.oj.service.entity.contest.ContestPrintEntityService;
import com.frank.oj.service.entity.contest.ContestRecordEntityService;
import com.frank.oj.shiro.AccountProfile;
import com.frank.oj.validator.GroupValidator;
import org.apache.shiro.SecurityUtils;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;

/**
 * @author frank
 * @Date 2024/4/21
 */
@Component
public class ContestAdminManager {
    @Resource
    private ContestEntityService contestEntityService;
    @Resource
    private ContestRecordEntityService contestRecordEntityService;
    @Resource
    private ContestPrintEntityService contestPrintEntityService;
    @Resource
    private GroupValidator groupValidator;

    public IPage<ContestPrint> getContestPrint(Long cid, Integer currentPage, Integer limit) throws StatusForbiddenException {
        AccountProfile userRole = (AccountProfile) SecurityUtils.getSubject().getPrincipal();
        boolean isRoot = SecurityUtils.getSubject().hasRole("root");

        Contest contest = contestEntityService.getById(cid);

        if (!isRoot && !contest.getUid().equals(userRole.getUid()) && !(contest.getIsGroup() && groupValidator.isGroupRoot(userRole.getUid(), contest.getGid()))) {
            throw new StatusForbiddenException("对不起，您无权限操作");
        }

        if (currentPage == null || currentPage < 1) currentPage = 1;
        if (limit == null || limit < 1) limit = 30;
        IPage<ContestPrint> contestPrintIPage = new Page<>(currentPage, limit);

        LambdaQueryWrapper<ContestPrint> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.select(ContestPrint::getId, ContestPrint::getCid, ContestPrint::getUsername, ContestPrint::getRealname, ContestPrint::getStatus, ContestPrint::getGmtCreate)
                .eq(ContestPrint::getCid, cid)
                .orderByAsc(ContestPrint::getStatus).orderByDesc(ContestPrint::getGmtCreate);

        return contestPrintEntityService.page(contestPrintIPage, queryWrapper);
    }

    public void checkContestPrintStatus(Long id, Long cid) throws StatusForbiddenException, StatusFailException {
        AccountProfile userRole = (AccountProfile) SecurityUtils.getSubject().getPrincipal();
        boolean isRoot = SecurityUtils.getSubject().hasRole("root");

        Contest contest = contestEntityService.getById(cid);
        if (!isRoot && !contest.getUid().equals(userRole.getUid()) && !(contest.getIsGroup() && groupValidator.isGroupRoot(userRole.getUid(), contest.getGid()))) {
            throw new StatusForbiddenException("对不起，您无权限操作");
        }

        boolean saved = contestPrintEntityService.saveOrUpdate(new ContestPrint().setId(id).setStatus(1));
        if (!saved) {
            throw new StatusFailException("操作失败");
        }
    }

    public IPage<ContestRecord> getContestACInfo(Long cid, Integer currentPage, Integer limit) throws StatusForbiddenException {
        AccountProfile userRole = (AccountProfile) SecurityUtils.getSubject().getPrincipal();
        boolean isRoot = SecurityUtils.getSubject().hasRole("root");

        // 获取本场比赛的状态
        Contest contest = contestEntityService.getById(cid);

        if (!isRoot && !contest.getUid().equals(userRole.getUid())
                && !(contest.getIsGroup() && groupValidator.isGroupRoot(userRole.getUid(), contest.getGid()))) {
            throw new StatusForbiddenException("对不起，您无权限操作！");
        }

        if (currentPage == null || currentPage < 1) currentPage = 1;
        if (limit == null || limit < 1) limit = 30;

        // 获取当前比赛的，状态为ac，未被校验的排在前面
        return contestRecordEntityService.getACInfo(currentPage,
                limit,
                Constants.Contest.RECORD_AC.getCode(),
                cid,
                contest.getUid(),
                contest.getStartTime(),
                contest.getEndTime());
    }

    public void checkContestACInfo(CheckACDTO checkACDto) throws StatusForbiddenException, StatusFailException {
        AccountProfile userRole = (AccountProfile) SecurityUtils.getSubject().getPrincipal();
        boolean isRoot = SecurityUtils.getSubject().hasRole("root");

        Contest contest = contestEntityService.getById(checkACDto.getCid());

        if (!isRoot
                && !contest.getUid().equals(userRole.getUid())
                && !(contest.getIsGroup() && groupValidator.isGroupRoot(userRole.getUid(), contest.getGid()))) {
            throw new StatusForbiddenException("对不起，您无权限操作！");
        }

        boolean isOk = contestRecordEntityService.updateById(
                new ContestRecord().setChecked(checkACDto.getChecked()).setId(checkACDto.getId()));

        if (!isOk) {
            throw new StatusFailException("修改失败！");
        }
    }
}
